import { toCamelCase } from "@/utils/func"
import { getApp } from ".."
import { ActionType, BelongsTo, checkOpType, Column, ColumnType, ElementType, HasOne, isNumber, OpType, TableColumn } from "../types"
import { isObject, isArray } from 'lodash-es'
import { FormRules } from "element-plus"
import { getElement } from "../elements"

/**
 *  [column]manager_id:  type: ref, rel: user.lookup.id
    [belongsTo]manager: [rel: user.lookup.id]
    [hasMany]organizationRoles: role_id: type: ref, rel: role.lookup.id
    [habtm]roles: []
  // micro.seed.action 在服务【micro】下去找
  // .seed.action 在应用下去找
  // seed.action 在当前所在的服务下去找
  // action 在当前seed下去找
 * @param column 
 * @returns 
 */
// export function getRefAction(column: Column) {
//   if(!column.rel) {
//     if(column.type == 'code') {
//       column.rel = 'tree.code'
//     } else {
//       throw Error(`请为列【${column.seed.name}.${column.name}】配置【rel】值`)
//     }
//   }

//   const pos = column.rel.lastIndexOf('.')
//   const rel = column.rel.substring(0, pos)
//   const items = rel.split('.')
//   const len = items.length
//   if(len == 1) { // 在当前seed下去找
//     const ret = column.seed.actions[rel]
//     if(!ret) throw Error(`元数据【${column.seed.name}】下不存在【${rel}】行为`)

//     return ret
//   }

//   const app = getApp()
//   if(len == 2) { //在当前所在的服务下去找
//     const [seedName, actionName] = items
//     const micro = column.micro
//     if(micro) {
//       // const ret = getLibAction(actionName, seedName, micro.libs)
//       // if(ret) return ret
  
//       const seed = micro.seeds[seedName]
//       if(seed) {
//         const ret = seed.actions[actionName]
//         if(ret) return ret
//       }
//     } else {
//       // const ret = getLibAction(actionName, seedName, app.libs)
//       // if(ret) return ret
    
//       const seed = app.seeds[seedName]
//       if(seed) {
//         const ret = seed.actions[actionName]
//         if(ret) return ret
//       }
//     }
//   }

//   if(len == 3) {
//     const [microName, seedName, actionName] = items
//     if(microName) { //在服务【micro】下去找
//       if(!app.micros && !app.micros[microName]) throw Error(`不存在【${rel}】行为`)

//       const micro = app.micros[microName]
//       // const ret = getLibAction(actionName, seedName, micro.libs)
//       // if(ret) return ret
  
//       const seed = micro.seeds[seedName]
//       if(seed) {
//         const ret = seed.actions[actionName]
//         if(ret) return ret
//       }
//     } else { // 在应用下去找
//       // const ret = getLibAction(actionName, seedName, app.libs)
//       // if(ret) return ret

//       if(!app.seeds) throw Error(`不存在【${rel}】行为`)

//       const seed = app.seeds[seedName]
//       if(seed) {
//         const ret = seed.actions[actionName]
//         if(ret) return ret
//       }
//     }
//   }

//   throw Error(`不存在【${rel}】行为`)
// }

export function toTableColumn(column: Column): TableColumn {
  const { name } = column
  return { ...column, field: toCamelCase(name), hidden: false }
}

export function formatSearch(search: string): [string, OpType] {
  if(!search.includes('_')) return [search, undefined]

  const pos = search.lastIndexOf('_')
  const fullColumn = search.substring(0, pos)
  const op = search.substring(pos + 1) as OpType
  checkOpType(op)
  return [fullColumn, op as OpType]
}

export function getOpByColumn(column: Column): OpType {
  switch(column.type) {
    case 'varchar':
    case 'tinytext':
    case 'text':
    case 'mediumtext':
    case 'longtext': return 'like'
    // case 'code': return 'like'
    case 'char':
    case 'bit':
    case 'file':
    case 'image':
    case 'avatar':
    case 'icon':
    case 'qrcode':
    case 'color':
    case 'ref':
    case 'enum':
    case 'yesno':
    case 'sex':
    case 'password':
    case 'tinyblob':
    case 'blob':
    case 'longblob':
    case 'binary':
    case 'varbinary':
    case 'json': return 'eq'
    case 'set': throw Error('没有相好')
    default: return 'between'
  }
}


export function getColumnValue(row, field: string) {
  if(!field.includes('.')) {
    const value = row[field]
    if(!value) return void 0
    return isObject(value) ? value['name'] : value
  }

  let value = row
  const items = field.split('.')
  for(const i in items) {
    if(!value) return void 0

    const item = items[i]
    if(isArray(value)) {
      const arrayValue = []
      for(const j in value) {
        const tmp = value[j]
        if(isArray(tmp)) {
          for(const k in tmp) arrayValue.push(tmp[k][item])
        } else {
          arrayValue.push(tmp[item])
        }
      }
      value = arrayValue
    } else {
      value = value[item]
    }
  }

  return isArray(value) ? value.join(',') : value
}

export function getRules(columns: Record<string, Column>): FormRules<Record<string, any>> {
  const ret = {}
  for(const columnName in columns) ret[toCamelCase(columnName)] = getValidates(columns[columnName])

  return ret
}

export function getValidates(column: Column) {
  const validates = []
  // if(column.type == 'code') {
  //   validates.push({
  //     validator: (_: any, value: any, callback: any) => {
  //       if (!value || value.endsWith('.')) {
  //         callback(new Error('编码不能为空'))
  //       } else {
  //         callback()
  //       }
  //     }
  //   })
  // }

  if(column.required) validates.push({ required: true, message: `${column.label || column.name}不能为空`, trigger: 'blur' })
  const min = column.min
  const max = getMax(column)
  const a = isNumber(column.type) ? '值' : '长度'
  if(min) {
    // validates.push({ min, max, message: `${a}只能在【${min}】和【${max}】之间`, trigger: 'blur' })
  } else {
    // validates.push({ max, message: `${a}不能超过【${max}】`, trigger: 'blur' })
  }

  return validates
}

function getMax(column: Column) {
  const length = getLength(column)
  return column.max ? (column.max > length ? length : column.max) : length
}

function getLength(column: Column) {
  if(column.length) return column.length

  // TODO
  switch(column.type) {
    case 'varchar': return 64
    default: return 64
  }
}

// micro.seed.action 在服务【micro】下去找
// .seed.action 在应用下去找
// seed.action 在当前所在的服务下去找
// action 在当前seed下去找
// export function getRelUrl(column: Column, defaultActionName = 'lookup') {
//   const { micro, seed } = column
//   if(!column.rel) return (micro ? `${micro.name}/` : '') + `${seed.name}/${defaultActionName}`

//   const pos = column.rel.lastIndexOf('.')
//   const rel = column.rel.substring(0, pos)
//   const items = rel.split('.')
//   const len = items.length
//   if(len == 1) return (micro ? `${micro.name}/` : '') + `${seed.name}/${rel}`
//   if(len == 2) return (micro ? `${micro.name}/` : '') + `${items[0]}/${items[1]}`
  
//   const [microName, seedName, actionName] = items
//   if(microName) return `${microName}/${seedName}/${actionName}`

//   return `${seedName}/${actionName}`
// }

// export function getColumnElement(column: Column, actionType: ActionType) {
//   if(column.element) return getElement(column.type, column.element)

//   switch(actionType) {
//     case 'save':
//     case 'update':
//     case 'set':
//       return getWritableElement(column.type)
//     default:
//       return getElement(column.type)
//   }
// }

// export function getWritableElement(columnType: ColumnType) {
//   const dict: Record<ElementType, string> = {
//     varchar: 'Input',
//     code: 'InputCode'
//   }
//   switch(columnType) {
//     case 'varchar':
//       return getElement(columnType, 'Input')
//     default:
//       return getElement(columnType)
//   }
// }
